package com.guojian.common.utils;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.Calendar;

import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang.time.DateFormatUtils;
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipOutputStream;
import org.springframework.util.FileCopyUtils;

/**
 * 文件读写
 * 
 * @author guojian
 *
 */
public class FileIOUtils extends FileCopyUtils {

	/**
	 * 写入文件(推荐使用spring的文件读写类)
	 * 
	 * @param in
	 * @param out
	 */
	public static void writeFile(InputStream in, OutputStream out, boolean isCloseOutStream, boolean isFlush) {
		byte[] buffer = new byte[1024 * 1024];
		int length = 0;
		try {
			while ((length = in.read(buffer)) > 0) {
				out.write(buffer, 0, length);
			}
		} catch (IOException e) {
			throw new RuntimeException("文件写入异常", e);
		} finally {
			try {
				in.close();
				if (isFlush) {
					out.flush();
				}
				if (isCloseOutStream) {
					out.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 一次性写入单个文件
	 * 
	 * @param in
	 * @param out
	 */
	public static void writeFile(InputStream in, OutputStream out) {
		writeFile(in, out, true, true);
	}

	/**
	 * 下载一个文件
	 * 
	 * @param files
	 * @param response
	 * @throws IOException
	 */
	public static boolean downloadFile(File[] files, HttpServletResponse response) throws IOException {
		if (files.length == 1) {
			File file = files[0];
			downloadFile(getFileName(file.getName()), file, response);
		} else if (files.length > 1) {
			downLoadZip(files, response);
		} else {
			throw new IOException("附件不存在");
		}
		return true;
	}

	/**
	 * 批量下载
	 * 
	 * @param files
	 * @param response
	 * @throws IOException
	 */
	public static void downLoadZip(File[] files, HttpServletResponse response) throws IOException {
		response.setContentType("application/octet-stream");// 任意类型的文件
		response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(DateFormatUtils.format(Calendar.getInstance(), "yyyyMMdd") + "批量.zip", "UTF-8"));
		ZipOutputStream zos = new ZipOutputStream(response.getOutputStream());
		zos.setEncoding("GBK");
		for (File file : files) {
			ZipEntry entry = new ZipEntry(getFileName(file.getName()));
			zos.putNextEntry(entry);
			writeFile(new FileInputStream(file), zos, false, false);
		}
		zos.flush();
		zos.close();
	}

	/**
	 * 根据文件列表,创建压缩包
	 * 
	 * @param files
	 * @param out
	 * @throws IOException
	 */
	public static void createZip(File[] files, OutputStream out) throws IOException {
		ZipOutputStream zos = new ZipOutputStream(out);
		zos.setEncoding("GBK");
		for (File file : files) {
			ZipEntry entry = new ZipEntry(getFileName(file.getName()));
			zos.putNextEntry(entry);
			writeFile(new FileInputStream(file), zos, false, false);
		}
		zos.flush();
		zos.close();
	}

	/**
	 * 向客户端输出文件流,让浏览器弹出下载框
	 * 
	 * @param fileName
	 * @param file
	 * @param response
	 * @throws IOException
	 */
	public static void downloadFile(String fileName, File file, HttpServletResponse response) throws IOException {
		response.setContentType("application/octet-stream");// 任意类型的文件
		response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
		response.setHeader("Content-Length", String.valueOf(file.length()));
		FileInputStream in = new FileInputStream(file);
		OutputStream out = response.getOutputStream();
		writeFile(in, out);
	}

	/**
	 * eg:5ff775e2-96ee-460d_b7dd_f4f514bd2d28_天津港8.12特别重大火灾爆炸事故案例.docx
	 * 
	 * @param fileName
	 * @return
	 */
	public static String getFileName(String fileName) {
		return FilenameUtils.getName(fileName);
	}

	public static void main(String[] args) {
		System.out.println(getFileName("1_天津港8.12特别重大火灾爆炸事故案例.docx"));
	}

}
